package com.wpp;


import org.junit.Test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/*
 * Java集合可分为Collection和Map两种体系
 *   Collection接口：单列数据，定义了存取一组对象的方法的集合
 *       List接口:元素有序、可重复的集合--->动态数组
 *           ArrayList、作为list接口的主要实现类、线程不安全的，效率高，底层使用Object[]存储
 *           LinkedList、对于频繁的插入删除操作，使用此类比ArrayList效率高，底层使用的是双向链表存储
 *           Vector、作为list接口的古老实现，线程安全的，效率低，底层使用Object[]存储
 *           相同点：存储有序的，可重复的数据
 *     --Set接口: 元 素无序，不可重复的集合--->
 *         --HashSet:作为Set接口的主要实现类，线程不安全的，可以存储null值
 *             --LinkedHashSet:作为HashSet的子类；遍历其内部数据时，可以按照添加的顺序遍历
 *                   LinkedHashSet作为HashSet的子类，在添加数据的同时，
 *                   每个数据还维护了两个引用，记录此数据的前数据和后数据
 *                   对于频繁的遍历操作，LinkedHashSet效率高于HashSet
 *         --TreeSet:可以按照添加对象的指定属性，进行排序；
 *                   向TreeSet中添加的数据，要求是相同类的对象
 *     Set接口：
 *           无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加，而是按照数据的哈希值所决定的
 *        不可重复性:相同的元素只能添加一个
 *        添加元素的过程，以HashSet为例:
 *           -----|我们向HashSet中添加元素a，首先调用元素a所在的hashCode()方法，计算元素a的哈希值，
 *              ----|此哈希值接着通过某种算法计算出在hashSet底层数组中的存放位置(即为：索引位置)，
 *                   -----|判断数组此位置上是否已经有元素，
 *                       ----|如果此位置上没有其他元素，则元素a添加成功
 *                       ----|如果此位置上有其他元素b，(或者已经存在以链表形式存在的多个元素)，首先比较元素a与元素b的哈希值，
 *                           ----|如果哈希值不相同，则元素a添加成功，
 *                           ----|如果哈希值相同，则需要调用元素a所在类的equals()；
 *                               ----|equals()返回true:则表示元素a添加失败
 *                               ----|equals()返回false:则表示元素a添加成功
 *
 *       对于添加成功的而言，元素a与已经存在指定索引位置上数据以链表的方式存储
 *           jdk7:元素a放到数组中，并且指向其他元素
 *           jdk8:原来的元素在数组中不动，但是需要指向元素a
 *       扩容方式：底层也是数组。初始容量为16，当如果使用率超过0.75，(16*0.75=12)
 *                就会扩大容量为原来的2倍，(16扩容为32,64,128等)
 *
 *       HashSet底层：数组+链表结构
 *       要求：向Set中添加的数据，其所在的类一定要重写hashCode()和equals()；
 *           重写的hashcode()和equals()尽可能的保持一致性；相等的对象必须具有相同的哈希值(散列码)
 *       LinkedHashSet的使用：
 *           LinkedHashSet作为HashSet的子类，在添加数据的同时，每个数据还维护了两个引用，记录此数据的前数据和后数据
 *
 *
 *
 * */
public class SetTest {

    @Test
    public void test() {
        Set hashSet = new HashSet();
        hashSet.add(32);
        System.out.println(hashSet.size());
        hashSet.add(132);
        hashSet.add(132);
        System.out.println(hashSet.size());

    }


    /*
     * 过滤重复数据，使用set不可重复的特性
     *
     * */
    @Test
    public void test1() {
        ArrayList arrayList = new ArrayList();
        arrayList.add(1);
        arrayList.add(1);
        arrayList.add(111);
        arrayList.add(12);
        arrayList.add(13);
        arrayList.add(13);

        HashSet hashSet = new HashSet();
        hashSet.addAll(arrayList);
        ArrayList arrayList1 = new ArrayList(hashSet);
        for (Object obj : arrayList1) {
            System.out.println(obj);

        }


    }

    /**
    *用于测试:
    *
    */
    @Test
    public void testList(){

        //两种体系：Collection单列数据，Map体系：键值对
        /*
        * 单列数据又分为list和set
        * list是可重复的，有序的集合  主要实现子类有------ArrayList linkList vectory
        * set是无序的，不可重复的 hashset linkhashset  TreeSet
        *
        * */

        ArrayList<Object> arrayList = new ArrayList<>();


    }


}
